fix: use arithmetic HexEncode instead of lookups#12
fix: use arithmetic HexEncode instead of lookups#12ChALkeR wants to merge 5 commits intonodejs:mainfrom
Conversation
|
Excellent. For some analysis, please see this article on my blog: Daniel Lemire, "Converting data to hexadecimal outputs quickly," in Daniel Lemire's blog, February 2, 2026, https://lemire.me/blog/2026/02/02/converting-data-to-hexadecimal-outputs-quickly/. |
|
This is not the fastest way yet though, there should be more optimizations possible, but now I estimate that the most significant part of the slowdown is on the wrapping code. @lemire pls s/Skovorora/Skovoroda/g 🙃 |
|
@ChALkeR I'll update your name. Sorry. What you have here is great and I don't recommend doing more. The better place to get fancier would be simdutf. We do invite contributions. |
src/nbytes.cpp
Outdated
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| -1, -1, -1, -1, -1, -1, -1, -1, -1}; | ||
|
|
||
| inline char nibble(uint8_t x) { return x + '0' + ((x > 9) * 39); } |
There was a problem hiding this comment.
Can you add a comment to this function and explain what it does?
There was a problem hiding this comment.
I think that if you express it as I did above, it does not require an explanation anymore.
Co-authored-by: Yagiz Nizipli <yagiz@nizipli.com>
|
Try uint8_t add = (x >= 10) ? ('a' - 10) : '0';
return x + add;GCC seems to like it better than what I originally proposed. |
|
@lemire Seems slightly worse on Linux (gcc?) and slightly better on macOS (clang?) |
What I see is that my last proposal is better than your original version under GCC, but slightly worse with LLVM. However, both are autovectorized in a worthwhile manner which would make your PR safe and performant. Also, the code is easier to understand. |
See nodejs/node#61609
This improves
Buffer#toString('hex')2-4xIn local tests on a MacBook, this improves
.toString('hex')throughput from ~2.24 GiB/sto ~9.53 GiB/son ~80 KiB chunksFor comparison,
Uint8Array#toHex()shows3.28 GiB/s.Benchmark CI: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/1790/console